home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
scheme
/
boxer
/
boxer.lha
/
dumper.lisp
< prev
next >
Wrap
Text File
|
1993-07-17
|
21KB
|
524 lines
;-*-mode: Lisp; Base: 8.; package: Boxer; fonts:cptfont -*-
;;; This is a machine independent binary dumper for the BOXER system
;;;
;;; (C) Copyright 1984, 1985 Massachusetts Institute of Technology
;;;
;;; Permission to use, copy, modify, distribute, and sell this software
;;; and its documentation for any purpose is hereby granted without fee,
;;; provided that the above copyright notice appear in all copies and that
;;; both that copyright notice and this permission notice appear in
;;; supporting documentation, and that the name of M.I.T. not be used in
;;; advertising or publicity pertaining to distribution of the software
;;; without specific, written prior permission. M.I.T. makes no
;;; representations about the suitability of this software for any
;;; purpose. It is provided "as is" without express or implied warranty.
;;;
;;;
;;; +-Data--+
;;; This file is part of the | BOXER | system.
;;; +-------+
;;;
;;; It is meant to convert box structure into a binary format for storing in files
;;;
;;; The boxer world has three kinds of objects which must be dumped out
;;; They are: CHARACTERS, ROWS, and BOXES.
;;;
;;; CHARACTERS are dumped out as themselves, that is, fixnums
;;;
;;; ROWS are essentially arrays of characters and are dumped out as such keeping in mind that
;;; some of the characters may be BOXES
;;;
;;; BOXES come in three major types. Regular, Port and Graphics.
;;; ALL boxes have to preserve their display info (i.e. desired size), their name,
;;; binding information (the STATIC-VARIABLES-ALIST) and the superior row
;;;
;;; GRAPHICS boxes have to dump out their bit-arrays (although in the case of turtle boxes
;;; it may be optional)
;;;
;;; REGULAR boxes will have to keep track of their inferior rows,
;;; and Any pointers to PORTS
;;;
;;; PORTS only have to keep track of the ported to box
;*********************************************************************************************
;* DUMPING FUNCTIONS *
;*********************************************************************************************
;;; Top level Dumping Function (this is called from BOXER and takes a <box> and a <filename>)
(DEFUN DUMP-TOP-LEVEL-BOX (BOX FILENAME &OPTIONAL FILE-ATTRIBUTE-LIST)
(UNLESS (GET (LOCF FILE-ATTRIBUTE-LIST) ':PACKAGE)
(PUTPROP (LOCF FILE-ATTRIBUTE-LIST) ':BOXER ':PACKAGE))
(WRITING-BIN-FILE (BOX STREAM FILENAME)
(DUMP-ATTRIBUTE-LIST FILE-ATTRIBUTE-LIST STREAM)
(TELL BOX :DUMP-SELF STREAM)))
;;;minimal debugging utilities...
(DEFMACRO TEST-ENVIRONMENT (&BODY BODY)
`(LET ((*BIN-LOAD-INDEX* 0)
(*BIN-LOAD-TABLE* (MAKE-ARRAY 1000))
(*BIN-NEXT-COMMAND-FUNCTION* 'BIN-LOAD-NEXT-COMMAND))
(PROGN . ,BODY)))
(DEFUN FILE-TESTER (PATHNAME BUFFER)
(WITH-OPEN-FILE (STREAM PATHNAME ':DIRECTION ':INPUT ':CHARACTERS NIL)
(ZWEI:WITH-EDITOR-STREAM
(OUT ':BUFFER-NAME BUFFER ':CREATE-P T)
(TEST-ENVIRONMENT
(*CATCH 'BIN-LOAD-DONE
(PRINT-OUT-LOOP STREAM OUT))))))
(DEFUN PRINT-SYMBOL-TABLE (PATHNAME BUFFER)
(WITH-OPEN-FILE (STREAM PATHNAME ':DIRECTION ':INPUT ':CHARACTERS NIL)
(ZWEI:WITH-EDITOR-STREAM
(OUT ':BUFFER-NAME BUFFER ':CREATE-P T)
(LOADING-BIN-FILE (STREAM 'BIN-LOAD-NEXT-COMMAND NIL)
(LET ((PACKAGE (PKG-FIND-PACKAGE 'BOXER)))
(BIN-LOAD-TOP-LEVEL STREAM))
(FORMAT OUT "~%~% *** THE LOAD TABLE ***~%")
(LOOP FOR I FROM 0 TO *BIN-LOAD-INDEX*
DO (FORMAT OUT "~%~o: ~s" I (AREF *BIN-LOAD-TABLE* I)))))))
(DEFUN DA-WHOLE-THING (PATHNAME BUFFER)
(FILE-TESTER PATHNAME BUFFER)
(PRINT-SYMBOL-TABLE PATHNAME BUFFER))
(DEFUN PRINT-OUT-LOOP (STREAM OUT &OPTIONAL (PAD NIL))
(LOOP
DOING (LET ((NUMBER (TELL STREAM :TYI)))
(WHEN PAD (FORMAT OUT " "))
(COND ((NOT (NUMBERP NUMBER)) (FORMAT OUT "~s~%" NUMBER))
((= NUMBER BIN-OP-EOF)(*THROW 'BIN-LOAD-DONE T))
((= NUMBER BIN-OP-END-OF-BOX)
(FORMAT OUT "~%BIN-OP-END-OF-BOX")
(*THROW 'BOX-DONE T))
((BIN-OP-DISPATCH *BIN-OP-COMMAND-NAME-TABLE*
(DECODE-BIN-OPCODE NUMBER))
(MULTIPLE-VALUE-BIND (INDEX ARG)
(DECODE-BIN-OPCODE NUMBER)
(PRINT-OUT-BIN-COMMAND STREAM INDEX ARG OUT)))
(T (FORMAT OUT "~o " NUMBER))))))
(DEFUN PRINT-OUT-BIN-COMMAND (INSTREAM INDEX ARG OUTSTREAM)
(LET ((COMMAND-NAME (BIN-OP-DISPATCH *BIN-OP-COMMAND-NAME-TABLE* INDEX)))
(COND ((MEMQ COMMAND-NAME '(BIN-OP-DOIT-BOX BIN-OP-DATA-BOX BIN-OP-PORT-BOX
BIN-OP-GRAPHICS-BOX BIN-OP-TURTLE-BOX))
(FORMAT OUTSTREAM "~%~S~%" COMMAND-NAME)
(*CATCH 'BOX-DONE
(PRINT-OUT-LOOP INSTREAM OUTSTREAM T)))
;; numbers
((EQ COMMAND-NAME 'BIN-OP-NUMBER-IMMEDIATE)
(FORMAT OUTSTREAM "~S~%" (FUNCALL 'LOAD-BIN-OP-NUMBER-IMMEDIATE INSTREAM ARG)))
((EQ COMMAND-NAME 'BIN-OP-POSITIVE-FIXNUM)
(FORMAT OUTSTREAM "~d~%" (FUNCALL 'LOAD-BIN-OP-POSITIVE-FIXNUM INSTREAM)))
((EQ COMMAND-NAME 'BIN-OP-NEGATIVE-FIXNUM)
(FORMAT OUTSTREAM "~d~%" (FUNCALL 'LOAD-BIN-OP-NEGATIVE-FIXNUM INSTREAM)))
((EQ COMMAND-NAME 'BIN-OP-POSITIVE-FLOAT)
(FORMAT OUTSTREAM "~S~%" (FUNCALL 'LOAD-BIN-OP-POSITIVE-FLOAT INSTREAM)))
((EQ COMMAND-NAME 'BIN-OP-NEGATIVE-FLOAT)
(FORMAT OUTSTREAM "~S~%" (FUNCALL 'LOAD-BIN-OP-NEGATIVE-FLOAT INSTREAM)))
;; strings
((EQ COMMAND-NAME 'BIN-OP-STRING-IMMEDIATE)
(FORMAT OUTSTREAM "~S ~%" (FUNCALL 'LOAD-BIN-OP-STRING-IMMEDIATE INSTREAM ARG)))
((NULL ARG)(FORMAT OUTSTREAM "~S~%" COMMAND-NAME))
(T (FORMAT OUTSTREAM "~S ~o~%" COMMAND-NAME ARG)))))
;*********************************************************************************************
(DEFUN START-BIN-FILE (STREAM)
(SEND *BIN-DUMP-TABLE* ':CLEAR-HASH)
(TELL STREAM :TYO BIN-OP-FORMAT-VERSION)
(DUMP-BOXER-THING *VERSION-NUMBER* STREAM))
(DEFUN END-BIN-FILE (STREAM)
(TELL STREAM :TYO BIN-OP-EOF)
(CLOSE STREAM)
(TELL STREAM :TRUENAME))
(DEFUN ENTER-TABLE (FORM &OPTIONAL STREAM (EXPLICIT NIL))
(WHEN EXPLICIT (TELL STREAM :TYO BIN-OP-TABLE-STORE))
(SEND *BIN-DUMP-TABLE* ':PUT-HASH FORM *BIN-DUMP-INDEX*)
(INCF *BIN-DUMP-INDEX*))
;; this is here so it will get open coded into DUMP-BOXER-THING
(DEFSUBST SIMPLE-CONS? (X)
(AND (LISTP X) (ATOM (CDR X)) (NOT-NULL (CDR X))))
(DEFUN DUMP-BOXER-THING (THING STREAM &AUX INDEX)
(COND ((SETQ INDEX (TELL *BIN-DUMP-TABLE* :GET-HASH THING))
;; thing is EQ to something which has already been dumped
(DUMP-TABLE-LOOKUP STREAM INDEX))
((SYMBOLP THING) (DUMP-SYMBOL THING STREAM))
((FIXP THING) (DUMP-FIXNUM THING STREAM))
((FLOATP THING) (DUMP-FLOAT THING STREAM))
((STRINGP THING) (DUMP-STRING THING STREAM))
((SIMPLE-CONS? THING) (DUMP-SIMPLE-CONS THING STREAM))
((LISTP THING) (DUMP-LIST THING STREAM))
((GRAPHICS-SHEET? THING) (DUMP-GRAPHICS-SHEET THING STREAM))
((ARRAYP THING) (DUMP-ARRAY THING STREAM))
;((CHA? THING) (DUMP-CHA THING STREAM))
((ROW? THING) (DUMP-ROW THING STREAM))
((BOX? THING) (DUMP-BOX THING STREAM))
((TURTLE? THING) (DUMP-TURTLE THING STREAM))
((GRAPHICS-OBJECT? THING) (DUMP-GRAPHICS-OBJECT THING STREAM))
(T
(FERROR "Sorry, don't know how to dump ~S " THING))))
(DEFUN DUMP-ATTRIBUTE-LIST (PLIST STREAM)
(LET ((PKG (GET (LOCF PLIST) ':PACKAGE)))
(AND PKG (SETQ *BIN-DUMP-PACKAGE* (PKG-FIND-PACKAGE PKG))))
(FUNCALL STREAM ':TYO BIN-OP-FILE-PROPERTY-LIST)
;; Put package prefixes on everything in the plist since it will be loaded in
;; the wrong package. This way the symbols in the plist will always
;; be loaded into exactly the same package they were dumped from,
;; while the rest of the symbols in the file will be free to follow
;; the usual rules for intern.
(LET ((*BIN-DUMP-PACKAGE* NIL))
(PUTPROP (LOCF PLIST) #-LMITI ':ROW-MAJOR #+LMITI ':COLUMN-MAJOR ':BIT-ARRAY-ORDER)
(DUMP-BOXER-THING PLIST STREAM)))
(DEFUN DUMP-TABLE-LOOKUP (STREAM INDEX)
(COND ((< INDEX %%BIN-OP-IM-ARG-SIZE)
;; will it fit into 20 bit immediate arg ?
(TELL STREAM :TYO (DPB BIN-OP-TABLE-FETCH-IMMEDIATE %%BIN-OP-HIGH INDEX)))
((< INDEX %%BIN-OP-ARG-SIZE)
;; will it fit into a 24 bit fixnum ?
(TELL STREAM :TYO BIN-OP-TABLE-FETCH)
(TELL STREAM :TYO INDEX))
(T
;; figure out what to do if there are > 64K objects some other time
(FERROR "The dump index ~D ,won't fit inside a 16 bit fixnum" INDEX))))
(DEFUN DUMP-SYMBOL (SYMBOL STREAM)
(ENTER-TABLE SYMBOL)
(COND ((NULL (SYMBOL-PACKAGE SYMBOL))
(TELL STREAM :TYO BIN-OP-PACKAGE-SYMBOL)
(DUMP-BOXER-THING 'NIL STREAM))
(T
(LET ((PACKAGE-STRING #-REL4(PKG-NAME (SYMBOL-PACKAGE SYMBOL))
#+REL4(IF (EQ SI:PKG-USER-PACKAGE (SYMBOL-PACKAGE SYMBOL))
;; A name with a colon (hopefully)
(PKG-NAME PKG-KEYWORD-PACKAGE)
(PKG-NAME (SYMBOL-PACKAGE SYMBOL)))))
(COND ((NULL PACKAGE-STRING)
(TELL STREAM :TYO BIN-OP-SYMBOL))
(T
(TELL STREAM :TYO BIN-OP-PACKAGE-SYMBOL)
(DUMP-BOXER-THING PACKAGE-STRING STREAM))))))
(DUMP-BOXER-THING (GET-PNAME SYMBOL) STREAM))
;; remember to leave a bit for the sign bit
(DEFSUBST SMALL-FIX? (NUMBER)
(< (- (ash %%BIN-OP-IM-ARG-SIZE -1)) NUMBER (ash %%BIN-OP-IM-ARG-SIZE -1)))
(DEFSUBST DUMP-SMALL-FIXNUM (NUMBER STREAM)
(TELL STREAM :TYO (DPB BIN-OP-NUMBER-IMMEDIATE %%BIN-OP-HIGH (LDB 0014 NUMBER))))
(DEFSUBST DUMP-LARGE-FIXNUM (NUMBER STREAM)
(COND ((MINUSP NUMBER)
(TELL STREAM :TYO BIN-OP-NEGATIVE-FIXNUM)
(LET ((LENGTH (// (+ (HAULONG (- NUMBER)) 15.) 16.)))
(DUMP-BOXER-THING LENGTH STREAM)
(LOOP FOR I FROM 0 BELOW LENGTH
FOR POS FROM 0 BY 16.
DO (TELL STREAM :TYO (LOAD-BYTE (- NUMBER) POS 16.)))))
(T
(TELL STREAM :TYO BIN-OP-POSITIVE-FIXNUM)
(LET ((LENGTH (// (+ (HAULONG NUMBER) 15.) 16.)))
(DUMP-BOXER-THING LENGTH STREAM)
(LOOP FOR I FROM 0 BELOW LENGTH
FOR POS FROM 0 BY 16.
DO (TELL STREAM :TYO (LOAD-BYTE NUMBER POS 16.)))))))
(DEFUN DUMP-FIXNUM (NUM STREAM)
(IF (SMALL-FIX? NUM)
(DUMP-SMALL-FIXNUM NUM STREAM)
(DUMP-LARGE-FIXNUM NUM STREAM)))
(DEFUN DUMP-FLOAT (NUMBER STREAM)
(IF ( NUMBER 0)
(TELL STREAM :TYO BIN-OP-POSITIVE-FLOAT)
(SETQ NUMBER (- NUMBER))
(TELL STREAM :TYO BIN-OP-NEGATIVE-FLOAT))
(LET ((MANTISSA (SI:FLONUM-MANTISSA NUMBER #-(OR LMITI 3600)(SMALL-FLOATP NUMBER) #+3600 NIL))
(EXPONENT (SI:FLONUM-EXPONENT NUMBER #-(OR LMITI 3600)(SMALL-FLOATP NUMBER) #+3600 NIL)))
(AND (ZEROP MANTISSA) (SETQ EXPONENT 0)) ;Mainly for looks sake
(DUMP-BOXER-THING MANTISSA STREAM)
(DUMP-BOXER-THING EXPONENT STREAM)))
(DEFUN DUMP-STRING (STRING STREAM)
(ENTER-TABLE STRING)
(LET ((LENGTH (STRING-LENGTH STRING)))
(IF (< LENGTH %%BIN-OP-IM-ARG-SIZE)
(TELL STREAM :TYO (DPB BIN-OP-STRING-IMMEDIATE %%BIN-OP-HIGH LENGTH))
(TELL STREAM :TYO BIN-OP-STRING)
(DUMP-BOXER-THING LENGTH STREAM))
(LOOP FOR I FROM 0 BELOW (BOOLE 2 1 LENGTH) BY 2 ;TV:ALU-ANDCA
DO (FUNCALL STREAM ':TYO (DPB (AREF STRING (1+ I)) 1010 (AREF STRING I)))
FINALLY (AND ( I LENGTH)
(FUNCALL STREAM ':TYO (AREF STRING I))))))
;; this is gross. It should be handled by DUMP-LIST. If you can figure out how to do it
;; right. then do it.
(DEFUN DUMP-SIMPLE-CONS (CONZ STREAM)
(ENTER-TABLE CONZ)
(TELL STREAM :TYO BIN-OP-SIMPLE-CONS)
(DUMP-BOXER-THING (CAR CONZ) STREAM)
(DUMP-BOXER-THING (CDR CONZ) STREAM))
;; this assumes that all lists want to get dumped as they are (i.e. EVALed at dump time)
(DEFUN DUMP-LIST (LIST STREAM)
(ENTER-TABLE LIST)
(LOOP FOR L ON LIST
COUNT T INTO LENGTH
AS DOTIFY = (ATOM L)
UNTIL DOTIFY
FINALLY (IF (< LENGTH %%BIN-OP-IM-ARG-SIZE)
(FUNCALL STREAM ':TYO
(DPB BIN-OP-LIST-IMMEDIATE %%BIN-OP-HIGH LENGTH))
(FUNCALL STREAM ':TYO BIN-OP-LIST)
(DUMP-BOXER-THING LENGTH STREAM))
(LOOP FOR I FROM 0 BELOW LENGTH
FOR L = LIST THEN (CDR L)
DO (DUMP-BOXER-THING (IF (AND DOTIFY (= I (1- LENGTH))) L (CAR L))
STREAM))))
(DEFUN DUMP-ARRAY (ARRAY STREAM)
(ENTER-TABLE ARRAY)
(MULTIPLE-VALUE-BIND (DIMENSIONS OPTIONS)
(DECODE-ARRAY ARRAY)
(IF (GET (LOCF OPTIONS) ':DISPLACED-TO)
(DUMP-ARRAY-1 STREAM DIMENSIONS OPTIONS)
(LET ((LENGTH (ARRAY-LENGTH ARRAY)) ;Flattened size
(N-BITS (CDR (ASSQ (GET (LOCF OPTIONS) ':TYPE) ARRAY-BITS-PER-ELEMENT))))
(COND ((NULL N-BITS) ;Q type array
(TELL STREAM :TYO BIN-OP-INITIALIZE-AND-RETURN-ARRAY)
(DUMP-ARRAY-1 STREAM DIMENSIONS OPTIONS)
(DUMP-BOXER-THING LENGTH STREAM)
(LET ((Q-ARRAY (IF (ATOM DIMENSIONS)
ARRAY
(MAKE-ARRAY LENGTH ':DISPLACED-TO ARRAY))))
(DOTIMES (I LENGTH)
(DUMP-BOXER-THING (AREF Q-ARRAY I) STREAM))
(OR (EQ ARRAY Q-ARRAY) (RETURN-ARRAY Q-ARRAY))))
(T
(LET ((16-ARRAY (IF (AND (ATOM DIMENSIONS) (= N-BITS 16.) )
ARRAY
(SETQ LENGTH (// (+ (* LENGTH N-BITS) 15.) 16.))
(MAKE-ARRAY LENGTH ':TYPE 'ART-16B
':DISPLACED-TO ARRAY))))
(TELL STREAM :TYO BIN-OP-INITIALIZE-AND-RETURN-NUMERIC-ARRAY)
(DUMP-ARRAY-1 STREAM DIMENSIONS OPTIONS)
(DUMP-BOXER-THING LENGTH STREAM)
(FUNCALL STREAM ':STRING-OUT 16-ARRAY 0 LENGTH)
(OR (EQ ARRAY 16-ARRAY) (RETURN-ARRAY 16-ARRAY)))))))))
(DEFUN DUMP-ARRAY-1 (STREAM DIMENSIONS OPTIONS)
(FUNCALL STREAM ':TYO (DPB BIN-OP-ARRAY %%BIN-OP-HIGH (// (LENGTH OPTIONS) 2)))
(DUMP-BOXER-THING DIMENSIONS STREAM)
(DOLIST (FORM OPTIONS)
(DUMP-BOXER-THING FORM STREAM)))
#-3600
(DEFVAR *BOOLEAN-TYPE-ARRAYS* NIL)
(DEFUN DECODE-ARRAY (ARRAY &AUX DIMENSIONS OPTIONS)
(DECLARE (VALUES DIMENSIONS ARRAY-OPTIONS))
(SETQ DIMENSIONS (IF (= (#-LMITI ARRAY-#-DIMS #+LMITI ARRAY-RANK ARRAY) 1) (ARRAY-LENGTH ARRAY)
(ARRAY-DIMENSIONS ARRAY)))
(LET ((TYPE (ARRAY-TYPE ARRAY)))
(OR (EQ TYPE 'ART-Q)
(SETQ OPTIONS `(:TYPE ,TYPE . ,OPTIONS))))
(AND (ARRAY-HAS-LEADER-P ARRAY)
(SETQ OPTIONS `(:LEADER-LIST ,(LIST-ARRAY-LEADER ARRAY) . ,OPTIONS)))
(AND (NAMED-STRUCTURE-P ARRAY)
(SETQ OPTIONS `(:NAMED-STRUCTURE-SYMBOL ,(#-LMITI NAMED-STRUCTURE-SYMBOL
#+LMITI NAMED-STRUCTURE-P ARRAY) . ,OPTIONS)))
(AND (ARRAY-DISPLACED-P ARRAY)
(LET ((TEM (SI:ARRAY-INDEX-OFFSET ARRAY)))
(SETQ OPTIONS `(:DISPLACED-TO ,(SI:ARRAY-INDIRECT-TO ARRAY)
,@(AND TEM `(:DISPLACED-INDEX-OFFSET ,TEM))
. ,OPTIONS))))
#-3600
(AND (MEMQ ARRAY *BOOLEAN-TYPE-ARRAYS*)
(PUTPROP (LOCF OPTIONS) 'SI:ART-BOOLEAN ':TYPE))
(VALUES DIMENSIONS OPTIONS))
;;; never gets called since they are dumped as fixnums first. Oh well...
(DEFUN DUMP-CHA (CHA STREAM)
(TELL STREAM :TYO (DPB BIN-OP-CHA-IMMEDIATE %%BIN-OP-HIGH CHA)))
(DEFUN DUMP-ROW (ROW STREAM)
(ENTER-TABLE ROW STREAM T)
(TELL ROW :DUMP-SELF STREAM))
(DEFMETHOD (ROW :DUMP-SELF) (STREAM)
(LET* ((CHAS (TELL SELF :CHAS))
(LENGTH (LENGTH CHAS)))
(IF (< LENGTH %%BIN-OP-IM-ARG-SIZE)
(TELL STREAM :TYO (DPB BIN-OP-ROW-IMMEDIATE %%BIN-OP-HIGH LENGTH))
(TELL STREAM :TYO BIN-OP-ROW)
(DUMP-BOXER-THING LENGTH STREAM))
(LOOP FOR CHA IN CHAS
DO (DUMP-BOXER-THING CHA STREAM))))
(DEFMETHOD (NAME-ROW :DUMP-SELF) (STREAM)
(LET* ((CHAS (TELL SELF :CHAS))
(LENGTH (LENGTH CHAS)))
(IF (< LENGTH %%BIN-OP-IM-ARG-SIZE)
(TELL STREAM :TYO (DPB BIN-OP-NAME-ROW-IMMEDIATE %%BIN-OP-HIGH LENGTH))
(TELL STREAM :TYO BIN-OP-NAME-ROW)
(DUMP-BOXER-THING LENGTH STREAM))
(DUMP-BOXER-THING CACHED-NAME STREAM)
(LOOP FOR CHA IN CHAS
DO (DUMP-BOXER-THING CHA STREAM))))
;(DEFMETHOD (NAME-AND-INPUT-ROW :DUMP-SELF) (STREAM)
; (LET* ((CHAS (TELL SELF :CHAS))
; (LENGTH (LENGTH CHAS)))
; (IF (< LENGTH %%BIN-OP-IM-ARG-SIZE)
; (TELL STREAM :TYO (DPB BIN-OP-NAME-AND-INPUT-ROW-IMMEDIATE %%BIN-OP-HIGH LENGTH))
; (TELL STREAM :TYO BIN-OP-NAME-AND-INPUT-ROW)
; (DUMP-BOXER-THING LENGTH STREAM))
; (DUMP-BOXER-THING CACHED-NAME STREAM)
; (LOOP FOR CHA IN CHAS
; DO (DUMP-BOXER-THING CHA STREAM))))
;;; Graphics dumping functions
(DEFUN DUMP-GRAPHICS-SHEET (SHEET STREAM)
(ENTER-TABLE SHEET)
(TELL STREAM :TYO BIN-OP-GRAPHICS-SHEET)
(DUMP-BOXER-THING (GRAPHICS-SHEET-DRAW-WID SHEET) STREAM)
(DUMP-BOXER-THING (GRAPHICS-SHEET-DRAW-HEI SHEET) STREAM)
(DUMP-BOXER-THING (GRAPHICS-SHEET-BIT-ARRAY SHEET) STREAM)
(DUMP-BOXER-THING (GRAPHICS-SHEET-DRAW-MODE SHEET) STREAM)
;(DUMP-BOXER-THING (GRAPHICS-SHEET-OBJECT-LIST SHEET) STREAM)
)
(DEFUN DUMP-GRAPHICS-OBJECT (OBJECT STREAM)
(ENTER-TABLE OBJECT STREAM T)
(TELL STREAM :TYO BIN-OP-GRAPHICS-OBJECT)
(DUMP-BOXER-THING (TELL OBJECT :DUMP-FORM) STREAM))
(DEFUN DUMP-TURTLE (TURTLE STREAM)
(ENTER-TABLE TURTLE STREAM T)
(TELL STREAM :TYO BIN-OP-TURTLE)
(DUMP-BOXER-THING (TELL TURTLE :DUMP-FORM) STREAM))
;;; box dumping methods. We will rely upon method combination to generate the right set
;;; of fixnums to dump.
;;; Specifically, each type of box has a main method which dumps values specific to the box
;;; type (i.e. bit-arrays for graphics boxes)
;;; Things that ALL boxes have to do are dumped by :BEFORE and :AFTER methods
;;; for vanilla boxes
;;; The correct BOX-BIN-OP is dumped by specific :BEFORE methods for each type of box
;;; We have to be careful with boxes that are built out of more than one level of box flavor
(DEFUN DUMP-BOX (BOX STREAM)
(ENTER-TABLE BOX STREAM T)
(TELL BOX :DUMP-SELF STREAM))
;;; :BEFORE methods
(DEFMETHOD (DOIT-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-DOIT-BOX))
(DEFMETHOD (DATA-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-DATA-BOX))
(DEFMETHOD (PORT-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-PORT-BOX))
(DEFMETHOD (GRAPHICS-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-GRAPHICS-BOX))
(DEFMETHOD (GRAPHICS-DATA-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-GRAPHICS-DATA-BOX))
(DEFMETHOD (SPRITE-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-SPRITE-BOX))
(DEFMETHOD (LL-BOX :BEFORE :DUMP-SELF) (STREAM)
(TELL STREAM :TYO BIN-OP-LL-BOX))
;;; these DEFUN-METHOD's are for error catching and making it easy to change formats
;;; for things like the binding scheme
(DEFUN-METHOD DUMP-BOX-NAME BOX (STREAM)
(COND ((OR (STRINGP NAME) (NAME-ROW? NAME))
(DUMP-BOXER-THING NAME STREAM))
((AND (SYMBOLP NAME) (EQ (SYMBOL-PACKAGE NAME) PKG-BU-PACKAGE))
(DUMP-BOXER-THING (MAKE-NAME-ROW (LIST (GET-PNAME NAME)) NAME) STREAM))
((NULL NAME)
(DUMP-BOXER-THING NAME STREAM))
(T
(FERROR
"Incompatible change, the instance var name, ~S is not a string or row" NAME))))
(DEFUN-METHOD DUMP-DISPLAY-STYLE BOX (STREAM)
(IF (LISTP DISPLAY-STYLE-LIST)
(DUMP-BOXER-THING DISPLAY-STYLE-LIST STREAM)
(FERROR "Incompatible change, the instance variable DISPLAY-STYLE-LIST is no longer a list")))
(DEFUN-METHOD DUMP-ENVIRONMENT BOX (STREAM)
(LET ((OLD-ENVIRONMENT STATIC-VARIABLES-ALIST))
(IF (OR (NULL STATIC-VARIABLES-ALIST) (LISTP STATIC-VARIABLES-ALIST))
(DUMP-BOXER-THING
;;if the box points to itself, we remove the binding before dumping
;; cause it will lose
(DELQ (RASSQ SELF STATIC-VARIABLES-ALIST) STATIC-VARIABLES-ALIST)
STREAM)
(FERROR "Incompatible change, the instance variable STATIC-VARIABLES-ALIST is no longer a list"))
(SETQ STATIC-VARIABLES-ALIST OLD-ENVIRONMENT)))
(DEFUN-METHOD DUMP-LOCAL-LIBRARY BOX (STREAM)
(IF (NOT (OR (LL-BOX? LOCAL-LIBRARY) (NULL LOCAL-LIBRARY)))
;; if it isn't one or the other, then some things in the loader will break also
(FERROR "unrecognized local library format")
(TELL STREAM :TYO BIN-OP-LL-BOX-PRESCENCE-MARKER)
(DUMP-BOXER-THING LOCAL-LIBRARY STREAM)))
(DEFMETHOD (BOX :BEFORE :DUMP-SELF) (STREAM)
(DUMP-BOX-NAME STREAM)
(DUMP-DISPLAY-STYLE STREAM)
(DUMP-ENVIRONMENT STREAM)
(DUMP-LOCAL-LIBRARY STREAM))
;;; MAIN methods
(DEFMETHOD (BOX :DUMP-SELF) (STREAM) ;for DATA and DOIT boxes
;; move to BOX :BEFORE method if we allow ports to graphics boxes
(LOOP FOR ROW IN (TELL SELF :ROWS)
DO (DUMP-BOXER-THING ROW STREAM)))
(DEFMETHOD (PORT-BOX :DUMP-SELF) (STREAM)
;; all we have to do now is to dump the ported to box
(COND ((NULL PORTS) (cl:cerror #.(cl:string "Continue Saving Anyway")
#.(cl:string "Can't find ported to box")))
((TELL PORTS :SUPERIOR? *OUTERMOST-DUMPING-BOX*)
(DUMP-BOXER-THING PORTS STREAM))
(T (cl:cerror #.(cl:string "Continue Saving Anyway")
#.(cl:string "The ported to box, ~S, will not get dumped") PORTS))))
(DEFMETHOD (GRAPHICS-BOX :DUMP-SELF) (STREAM)
(DUMP-BOXER-THING GRAPHICS-SHEET STREAM)
(LOOP FOR ROW IN (TELL SELF :ROWS)
DO (DUMP-BOXER-THING ROW STREAM)))
(DEFMETHOD (GRAPHICS-DATA-BOX :DUMP-SELF) (STREAM)
(DUMP-BOXER-THING GRAPHICS-SHEET STREAM)
(LOOP FOR ROW IN (TELL SELF :ROWS)
DO (DUMP-BOXER-THING ROW STREAM)))
(DEFMETHOD (SPRITE-BOX :DUMP-SELF) (STREAM)
(DUMP-BOXER-THING ASSOCIATED-TURTLE STREAM)
(LOOP FOR ROW IN (TELL SELF :ROWS)
DO (DUMP-BOXER-THING ROW STREAM)))
(DEFMETHOD (BOX :AFTER :DUMP-SELF) (STREAM)
(DUMP-BOXER-THING EXPORTS STREAM)
(TELL STREAM :TYO BIN-OP-END-OF-BOX))